#!/usr/bin/perl
use strict;
use warnings;

# setup repo-specific hooks

# code is too long, but if you take out all the error/safety/sanity checks,
# it's basically just creating a symlink in <repo.git>/hooks pointing to some
# file inside $rc{LOCAL_CODE}/hooks/repo-specific

use lib $ENV{GL_LIBDIR};
use Gitolite::Rc;
use Gitolite::Common;

_die "repo-specific-hooks: LOCAL_CODE not defined in rc" unless $rc{LOCAL_CODE};
_die "repo-specific-hooks: '$rc{LOCAL_CODE}' does not exist or is not a directory" unless -d $rc{LOCAL_CODE};

_chdir( $ENV{GL_REPO_BASE} );

@ARGV = ("gitolite list-phy-repos | gitolite git-config -r % gitolite-options\\.hook\\. |");

while (<>) {
    chomp;
    my ( $repo, $hook, $code ) = split /\t/, $_;

    # we don't allow fiddling with the admin repo
    if ( $repo eq 'gitolite-admin' ) {
        _warn "repo-specific-hooks: ignoring attempts to set hooks for the admin repo";
        next;
    }

    # get the hook name
    $hook =~ s/^gitolite-options\.hook\.//;

    unless ( $hook =~ /^(pre-receive|post-receive|post-update)$/ ) {
        _warn "repo-specific-hooks: '$hook' is not one of the 3 hooks allowed, ignoring";
        next;
    }

    if ( $code =~ m(^/|\.\.) ) {
        _warn "repo-specific-hooks: double dot or leading slash not allowed in '$code'";
        next;
    }

    my $src = $rc{LOCAL_CODE} . "/hooks/repo-specific/$code";
    my $dst = "$repo.git/hooks/$hook";
    unless ( -x $src ) {
        _warn "repo-specific-hooks: '$src' doesn't exist or is not executable";
        next;
    }
    unlink $dst;
    symlink $src, $dst or _warn "could not symlink '$src' to '$dst'";
    # no sanity checks for multiple overwrites of the same hook
}
